<template>
    <div class="person">
        <h1>情况四:监视[ref]或[reactive]定义的[对象类型]数据中的某个属性</h1>
        <h2>姓名:{{ person.name }}</h2>
        <h2>年龄:{{ person.age }}</h2>
        <h2>汽车:{{ person.car.c1 }} | {{ person.car.c2 }}</h2>
        <hr>
        <button @click="changeName">修改名字</button>
        <button @click="changeAge">修改年龄</button>
        <button @click="changeFirstCar">修改第一台车</button>
        <button @click="changeSecondCar">修改第二台车</button>
        <button @click="changeAllCar">修改所有车</button>
    </div>
</template>

<script lang="ts" setup name="Person">
import { ref, reactive, watch } from 'vue'


let person = reactive({ name: '张三', age: 18, car: { c1: '海豹', c2: '海豚' } }) // 数据

function changeName() { // 方法
    person.name += '^-^'
}
function changeAge() {
    person.age += 2
}
function changeFirstCar() {
    person.car.c1 = '唐 DMI'
}
function changeSecondCar() {
    person.car.c2 = '元 ~'
}
function changeAllCar() {
    person.car = { c1: '秦 plus', c2: '宋 EV' }
}

/**
 * 监视,情况四:监视响应式对象中的某个属性,且该属性是基本类型的,要写成函数式
 */
watch(() => person.name, (nv, ov) => {
    console.log(nv, ov);
})
watch(() => person.age, (nv, ov) => {
    console.log(nv, ov);
})
/**
 * 监视,情况四:监视响应式对象中的某个属性,且该属性是对象类型的,
 * 可以直接写,也能写函数,更推荐写函数
 * 
 * 结论:监视的要是对象里的属性,那么最好写函数式,
 * 注意:若对象监视的是地址值,需要关注对象内部,需要手动开启深度监视
 */
watch(() => person.car, (nv, ov) => {
    console.log(nv, ov);
}, { deep: true })
</script>

<style scoped>
.person {
    background-color: skyblue;
    box-shadow: 0 0 10px;
    border-radius: 10px;
    padding: 20px;
}

button {
    margin: 0 5px;
}

li {
    font-size: 20px;
}
</style>
